package com.morpheus.redis.redisson.api.limiting;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.IntegerCodec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DcsRateLimit {
	private static final Logger LOGGER = LoggerFactory.getLogger(DcsRateLimit.class);
	private RedissonClient redisClient = null;
	private String key = null;
	private int limiter = 1000;

	public DcsRateLimit(RedissonClient redisClient, String key, int limiter) {
		this.redisClient = redisClient;
		this.key = key;
		this.limiter = limiter;
	}

	public void init() {
		RMapCache<String, Integer> msgRateLimit = this.redisClient.getMapCache(this.key, IntegerCodec.INSTANCE);
		if (msgRateLimit.containsKey(this.key)) {
			msgRateLimit.delete();
		}
	}

	public boolean overrun(RateLimitCallback callback, Object... args) {
		RMapCache<String, Integer> msgRateLimit = redisClient.getMapCache(this.key, IntegerCodec.INSTANCE);
		Integer count;
		try {
			msgRateLimit.putIfAbsent(this.key, 0, 1L, TimeUnit.SECONDS);
			count = msgRateLimit.addAndGet(key, 1);
			LOGGER.info("DcsRateLimit.overrun() count={}", count);
			if (count < limiter) {
				// 此处是你要执行的代码
				Object result = callback.call(args);
				LOGGER.info("DcsRateLimit.overrun() result={}", result);
				return true;
			}
			LOGGER.warn("超过限流:{}", count);
		} catch (Throwable th) {
			LOGGER.error("DcsRateLimit.overrun() throwable", th);
		}
		return false;
	}

	public static interface RateLimitCallback {
		public Object call(Object... args);
	}
}
